#!/bin/bash

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# 默认配置
CONFIG_FILE=".env"
MYSQL_ROOT_PASSWORD="root"
MYSQL_VERSION="8.0"
REDIS_VERSION="7.0.12"
NGINX_VERSION="latest"
SPRINGBOOT_APP_NAME="chinese-medicine-manage.jar"
SPRINGBOOT_APP_PORT="8080"
SPRINGBOOT_APP_PATH="./target"  # Spring Boot jar包所在目录
SPRINGBOOT_PROFILES="prod"      # Spring Boot 运行环境
SPRINGBOOT_OPTS="-Xmx512m"     # JVM 参数
NGINX_CONFIG="/home/nginx/conf/nginx.conf"
STATIC_FILES="/home/nginx/html"
NETWORK_NAME="my_network"
MYSQL_DATA_VOLUME="mysql_data"
ACTION="start"
USE_DOCKERFILE="true"          # 是否使用Dockerfile构建

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO] $1${NC}"
}

log_warn() {
    echo -e "${YELLOW}[WARN] $1${NC}"
}

log_error() {
    echo -e "${RED}[ERROR] $1${NC}"
}

# 显示帮助信息
show_help() {
    echo "使用方法: $0 [选项]"
    echo "选项:"
    echo "  -a, --action     执行动作 (start|stop|restart|clean) 默认: start"
    echo "  -c, --config     指定配置文件路径 默认: .env"
    echo "  -h, --help       显示帮助信息"
    echo "示例:"
    echo "  $0 --action start"
    echo "  $0 --action stop"
    echo "  $0 --config custom.env"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
        -a|--action)
            ACTION="$2"
            shift 2
            ;;
        -c|--config)
            CONFIG_FILE="$2"
            shift 2
            ;;
        -h|--help)
            show_help
            exit 0
            ;;
        *)
            log_error "未知参数: $1"
            show_help
            exit 1
            ;;
    esac
done

# 加载配置文件
if [ -f "$CONFIG_FILE" ]; then
    log_info "加载配置文件: $CONFIG_FILE"
    source "$CONFIG_FILE"
else
    log_warn "配置文件 $CONFIG_FILE 不存在，使用默认配置"
fi

# 检查Docker是否运行
check_docker() {
    if ! docker info >/dev/null 2>&1; then
        log_error "Docker未运行，请先启动Docker服务"
        exit 1
    fi
}

# 检查容器健康状态
check_container_health() {
    local container_name=$1
    local max_attempts=30
    local attempt=1

    while [ $attempt -le $max_attempts ]; do
        if [ "$(docker inspect -f {{.State.Running}} $container_name 2>/dev/null)" = "true" ]; then
            log_info "$container_name 已成功启动"
            return 0
        fi
        log_warn "等待 $container_name 启动... ($attempt/$max_attempts)"
        sleep 2
        ((attempt++))
    done
    
    log_error "$container_name 启动失败"
    return 1
}

# 停止并删除容器
stop_containers() {
    log_info "停止并删除容器..."
    docker stop mysql redis nginx springboot-app 2>/dev/null
    docker rm mysql redis nginx springboot-app 2>/dev/null
}

# 清理资源
clean_resources() {
    log_info "清理资源..."
    stop_containers
    docker network rm $NETWORK_NAME 2>/dev/null
    docker volume rm $MYSQL_DATA_VOLUME 2>/dev/null
    rm -rf /tmp/nginx-static 2>/dev/null
}

# 检查Spring Boot应用
check_springboot() {
    local jar_path="$SPRINGBOOT_APP_PATH/$SPRINGBOOT_APP_NAME"
    if [ "$USE_DOCKERFILE" = "false" ]; then
        if [ ! -f "$jar_path" ]; then
            log_error "Spring Boot应用jar包不存在: $jar_path"
            exit 1
        fi
        log_info "找到Spring Boot应用: $jar_path"
    else
        if [ ! -f "Dockerfile" ]; then
            log_error "Dockerfile不存在"
            exit 1
        fi
        log_info "使用Dockerfile构建应用"
    fi
}

# 启动服务
start_services() {
    check_docker

    # 创建网络
    log_info "创建网络..."
    docker network create $NETWORK_NAME 2>/dev/null || true

    # MySQL
    log_info "启动MySQL..."
    docker volume create $MYSQL_DATA_VOLUME 2>/dev/null || true
    docker run -d \
        --name mysql \
        --network $NETWORK_NAME \
        --restart unless-stopped \
        -p 3306:3306 \
        -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \
        -v $MYSQL_DATA_VOLUME:/var/lib/mysql \
        mysql:$MYSQL_VERSION
    check_container_health "mysql"

    # Redis
    log_info "启动Redis..."
    docker run -d \
        --name redis \
        --network $NETWORK_NAME \
        --restart unless-stopped \
        -p 6379:6379 \
        redis:$REDIS_VERSION
    check_container_health "redis"

    # Spring Boot应用
    log_info "准备启动Spring Boot应用..."
    check_springboot
    
    if [ "$USE_DOCKERFILE" = "true" ]; then
        log_info "使用Dockerfile构建并启动Spring Boot应用..."
        docker build -t springboot-app . -f Dockerfile
        docker run -d \
            --name springboot-app \
            --network $NETWORK_NAME \
            --restart unless-stopped \
            -p $SPRINGBOOT_APP_PORT:$SPRINGBOOT_APP_PORT \
            springboot-app
    else
        log_info "直接启动Spring Boot jar包..."
        docker run -d \
            --name springboot-app \
            --network $NETWORK_NAME \
            --restart unless-stopped \
            -p $SPRINGBOOT_APP_PORT:$SPRINGBOOT_APP_PORT \
            -v "$SPRINGBOOT_APP_PATH:/app" \
            -w /app \
            openjdk:17-jre \
            java $SPRINGBOOT_OPTS -jar $SPRINGBOOT_APP_NAME \
            --spring.profiles.active=$SPRINGBOOT_PROFILES
    fi
    check_container_health "springboot-app"

    # Nginx
    log_info "启动Nginx..."
    TEMP_STATIC_DIR="/tmp/nginx-static"
    mkdir -p $TEMP_STATIC_DIR
    if [ -d "$STATIC_FILES" ]; then
        cp -r $STATIC_FILES/* $TEMP_STATIC_DIR/
    else
        log_warn "静态文件目录不存在: $STATIC_FILES"
    fi
    docker run -d \
        --name nginx \
        --network $NETWORK_NAME \
        --restart unless-stopped \
        -p 80:80 \
        -v $TEMP_STATIC_DIR:/usr/share/nginx/html \
        -v $NGINX_CONFIG:/etc/nginx/nginx.conf \
        nginx:$NGINX_VERSION
    check_container_health "nginx"
}

# 主程序
case $ACTION in
    start)
        log_info "开始部署服务..."
        start_services
        ;;
    stop)
        log_info "停止所有服务..."
        stop_containers
        ;;
    restart)
        log_info "重启所有服务..."
        stop_containers
        start_services
        ;;
    clean)
        log_info "清理所有资源..."
        clean_resources
        ;;
    *)
        log_error "未知动作: $ACTION"
        show_help
        exit 1
        ;;
esac

log_info "操作完成!"